
#pragma once

#include "atr/core/boolean.hpp"
#include "atr/core/types.hpp"
#include "atr/containers/access/at.hpp"

namespace atr {

/**
 * @brief Namespace only for internal use of atr library
 * @details Please don't use this namespace outside the atr library. IF you REALLY need to - do it with special care.
 */
namespace __ {

template <typename ... Types>                           struct __access
    {};

template <typename Type>
struct __access<Type>
{
    using front = Type;
    using back  = Type;

    template <unsigned long Position>
    using at = typename __at<Position, Type>::type;
};

template <typename First, typename Second, typename ... Types>
struct __access<First, Second, Types...>
    : public __access<Second, Types...>
{
    using front = First;

    template <unsigned long Position>
    using at = typename __at<Position, First, Second, Types...>::type;
};

} // namespace __
} // namespace atr